Copyright: CopyRight ® South Pacific Information Services Ltd


    TCompress V1.5

File and Database Compression Components for Delphi

Registration   Installation   TCompress   TCDBMemo  TCDBImage

Copyright (c) 1995, South Pacific Information Services Ltd

Fax: +64-3-384-5138    Email: nzsm@spis.southern.co.nz

Key features:

•	 Multi-file compressed archives

•	 Database BLOB (memo, image) compression

•	 In-memory compression using streams

•	 Event hooks for customizable user interaction

•	 Built-in RLE (Run-Length Encoding) and LZH (Lempel-Ziv-Huffman) compression

•	Custom compression routines may be added

Contents:

Registration

Installation

COMPDEMO application

Introduction To Data Compression

Using TCompress

Using TCDBMemo

Using TCDBImage

TCompress Component

TCDBMemo Component

TCDBImage Component

TCBlobField Component

Troubleshooting

These components are provided as-is. There are no warranties, expressed or implied. In no event will South Pacific Information Services Ltd be liable to you for damages, including any loss of profits, data or other incidental or consequential damages arising out of your use or inability to use the components.  By installing and making use of TCompress, you indicate acceptance of these conditions.

We encourage you to report any difficulties or limitations you  may encounter so that we can consider improvements for everyone.


Registration

Registration and License fee: $US 45, £UK 30 or $NZ 70

Full source code of the Compress component (only) is also available for an additional $US 35, £UK 25 or $NZ 55

On registering, you will receive:

•	Your personal Registration Number, which will eliminate the reminder dialog

•	Many additional source code examples, including LZW compression source

•	The latest version, if updated

•	Our thanks for supporting quality products for Delphi developers

We accept registrations via Mastercard, Visa or check in the appropriate currency. US registrations can be made using the Internet's First Virtual Payment system (see below).

To register the TCompress Component set, let us know:

•	Your full name and return email or postal address

•	If applicable, credit card type (MC/Visa), number, expiry date and holder's name

•	What version of TCompress you have now (check the title of this Window)

•	What you want (i.e. components only, or components + TCompress source)

NB: Email is not secure! If you email credit card details, UUENCODE your entire message first.

United States:

Martha Moore, Delphi Shareware

3439 Moorland Avenue

Santa Rosa, CA 95407

Fax: 707-586-1183

Email: ann@href.com    Web page: http://super.sonic.net/ann/delphi/more

To register and pay using the Internet's First Virtual payment system, visit the Web page and follow the instructions there.

United Kingdom:

Rafe Aldridge

89 Sharland Close

Grove, Oxon, OX12 0AF

Fax/Tel: +44-1235-769-781    Email: tcompress@rcai.demon.co.uk

NB: UK payments can be made by cheque or money order only. Credit card payments in New Zealand currency can be made by contacting SPIS Ltd directly (below).

New Zealand:

South Pacific Information Services Ltd

PO Box 19-760, Christchurch, New Zealand

Fax: +64-3-384-5138   Tel: +64-3-384-5137

Email: nzsm@spis.southern.co.nz   Support BBS: +64-3-384-5138


Installation

(Users of TCompress V1.0 should first see the additional notes in HISTORY.TXT)

Quick Start (for people in a hurry):

•	Install  compress.dcu and compctrl.dcu

•	Load the COMPDEMO project, compile and run it

•	Examine compmain.pas for numerous examples of how to use the compression components

Installation Instructions (for careful people):

•	BACKUP your \delphi\bin\complib.dcl file

•	Also BACKUP the \delphi\demos\data\BIOLIFE.* files, as this database is used by COMPDEMO to show off blob compression

•	Put compress.dcu/.dcr and compctrl.dcu/.dcr in a directory on Delphi's Component Library Search path (see Options|Environment|Library if you want to alter this path)

•	Select Options|Install Components, then click Add and type compress. Click Add again and type compctrl. Click OK.

•	All being well, a rebuild will take place and a new Compress tab will appear on your component palette. This contains the Compress, CDBMemo (Compressed Database Memo) and CDBImage (Compressed Database Image) components.

•	Ensure the DBDEMOS alias is pointing to the directory containing the BIOLIFE database

•	Load the COMPDEMO project, compile and run it.

Notes:

•	If you don't intend to use Blob (memo/image) database compression, remove the compctrl unit from your library (Options|Install Components). However, you will need it installed initially if you wish to try all the features of COMPDEMO.

•	TCompress and its companions provide very comprehensive data compression capabilities. Don't let this intimidate you -- most developers might only need to drop TCompress on a form and call its ExpandFile/CompressFile methods and no more... or maybe drop CDBMemo/CDBImage components on as well and simply interact with them.

•	Registered users will receive still more source code examples.

Installing Help (for design-time help):

•	Put this help file in \delphi\bin, and the compress.kwf file in \delphi\help.

•	Run \delphi\help\helpinst, and select File|Open|\delphi\bin\delphi.hdx.

•	Click the + icon and select compress.kwf.

•	Select File|Save to write the updated .hdx file, then exit

•	You should now be able to access this help from within Delphi, e.g. by pressing F1 while the cursor is in the CompressSource property


COMPDEMO Application

This application demonstrates the main features of TCompress, using a simple drag-and-drop user interface.

See installation to set your system up to properly compile and run COMPDEMO.

Once it is running, select the desired compression method using the radio buttons, then drag files, images or memo text to and from the various components on the screen. In general, everything can be dragged everywhere, and compression or expansion is automatic.

You can change the archive name and path (top right), and you can change directories (center left) to expand or compress files to/from different directories. The entire archive can be expanded to the current directory by dragging the grey panel which holds the archive list.

Images and text from the compressed BIOLIFE database fields at the bottom of the screen can be dragged into and out of the directory or archive lists, and images can be dragged to and from the picture panel (a simple TImage) in the center of the screen.

Once you have a feel for how COMPDEMO works, have a look at the code in compmain.pas -- the TCompress interface routines are near the top; the rest is there to provide for the drag-and-drop interface. Just scan the code for references to the Compress1, CDBImage1 and CDBMemo1 components.

For a simple database application, you'd just need to drop a TCompress and one or more TCDBMemo/TCDBImage components on, set them up, and away you go -- no coding required...


Introduction To Data Compression

Data compression encodes data so that it uses fewer bytes than usual. The amount of compression depends on the nature (content) of the data and the algorithm used.

Here are some typical examples -- your compression may vary:

Algorithm:          RLE       LZH       LZW

BMP images  50-65%    90-98%    90-95%

Text files         0-10%    30-55%    25-40%

DB files          30-50%    55-90%    50-80%

Data compression takes time. However, with a fast CPU, the time lost in data compression (done once) is often balanced by a gain at expansion time (done frequently) due to a reduction in disk or network access.

One point about data compression: occasionally, a file cannot be compressed (try compressing a ''.zip'' file, for example). When that happens, TCompress will store the original data as-is, rather than a ''compressed'' copy.

Data compression is often used to ''archive'' files -- store multiple files in a compressed archive. TCompress includes easy-to-use multi-file archive functions.

TCompress's two built-in algorithms:

RLE: Run-Length-Encoding

This simple, quick compression replaces repeated characters (e.g. aaaaaaaaaaaa) with a ''counter'' code (e.g. 12a). It is most effective when you have numerous character repeats, such as in BMP files. It is least effective where such sequences are rare, such as in most text.

LZH: Lempel-Ziv-Huffman

The compression method is popular with compression utilities such as LHArc and others. Although its compression time is fairly slow, expansion is quick and it can achieve remarkable compression performance.

The source of the following algorithm is supplied free of charge to registered users of TCompress. However, its use is covered by US Patent Number 4,558,302, which requires a license from Unisys (a typical royalty is 0.95% of your application's retail price).

LZW: Lempel-Ziv-Welch

The LZW algorithm is one of the best general-purpose compression algorithms.  Many hardware and software products (such as high speed modems or .GIF files) use this algorithm because of its efficient compression and processing speed.


    Using TCompress

TCompress Reference

Purpose

Use the TCompress component to compress data from files, memory or database blobs into other files, memory or database blobs.

As supplied, TCompress supports LZH and RLE compression. You can also add custom compression routines (such as LZW) using the OnCompress, OnExpand and OnRecognize Events.

The OnCheckFile Event allows you to manage the user interaction involved in working with multi-file archives.

Tasks

•	To compress, view and expand files in a multi-file archive, use the CompressFiles, ExpandFiles, DeleteFiles and ScanCompressedFile methods.

•	To compress files to a stream (e.g. TMemoryStream or TBlobStream), use the CompressFilesToStream, ExpandFilesFromStream and ScanCompressedStream methods.

•	To compress a single item from one stream to another with an archive header, use Compress and Expand.

•	To compress from one stream to another directly (no header) use DoCompress and DoExpand.

•	To provide your own user interface for multi-file archive handling, or to vary the filenames/paths stored in an archive, write a handler for the OnCheckFile event.

•	To provide custom compression routines, write handlers for the OnCompress, OnExpand and OnRecognize events.


    Using TCDBMemo

TCDBMemo Reference  TDBMemo Reference

Purpose

Use the TCDBMemo component to compress the text data stored in database memo fields.

TCDBMemo offers exactly the same features as Delphi's TDBMemo, except that you can link it to a TCompress component to automatically compress/expand the data as it is accessed.

Until the CompressSource and CompressionMethod properties are specified, the TCDBMemo will behave just like a regular TDBMemo. (Even after they are specified, you will still be able to access uncompressed as well as compressed data with this component).

Setting Up Your Component

•	Start by dropping a TCompress component on your form

•	Select the TCDBMemo component and set its CompressSource property to the new TCompress component

•	Select the desired CompressionMethod

•	Specify a DataSource and DataField for your component

Special Note

•	The field you specify should not already be in the fields list of the TTable or TQuery to which the Datasource is linked. If it is, remove it.

Using Your Component

•	Once your component is set up, it will automatically compress data written to its field. Existing records will be untouched unless the field is updated (e.g. amended or cut-and-pasted over itself).

•	If data compression does not make a field smaller, the uncompressed contents of the field are kept rather than the ''compressed'' form

Compatibility Limitations

•	Fields compressed with TCDBMemo will naturally not be directly understandable to external applications (including ReportSmith).

•	Operations which work at the Borland Database Engine level (e.g. queries looking for keywords) may not find meaningful data.

•	Thus, the ''compressed BLOB'' solution is strictly for Delphi apps until such time that Borland rewrite the BDE to provide true, in-built compression. This is unlikely.


    Using TCDBImage

TCDBImage Reference  TDBImage Reference

Purpose

Use the TCDBImage component to compress the pictures stored in Image fields in your database.

CDBImage offers exactly the same features as Delphi's TDBImage, except that you can link it to a TCompress component to automatically compress/expand the data as it is accessed.

Until the CompressSource and CompressionMethod properties are specified, TCDBImage will behave just like a regular TDBImage. (Even after they are specified, you will still be able to access uncompressed as well as compressed data with this component).

Setting Up Your Component

•	Start by dropping a TCompress component on your form

•	Select the TCDBImage component and set its CompressSource property to the new TCompress component

•	Select the desired CompressionMethod

•	Specify a DataSource and DataField for your component

Special Note

•	The field you specify should not already be in the fields list of the TTable or TQuery to which the Datasource is linked. If it is, remove it.

Using Your Component

•	Once your component is set up, it will automatically compress data written to its field. Existing records will be untouched unless the field is updated (e.g. amended or cut-and-pasted over itself).

•	If data compression does not make a field smaller, the uncompressed contents of the field are kept rather than the ''compressed'' form

Compatibility Limitations

•	Fields compressed with TCDBImage will naturally not be directly understandable to external applications (including ReportSmith).

•	Operations which work at the Borland Database Engine level may not find meaningful data if they expect to find an uncompressed image.

•	Thus, the ''compressed BLOB'' solution is strictly for Delphi apps until such time that Borland rewrite the BDE to provide true, in-built compression. This is unlikely.


    TCompress Component

Properties         Methods         Events         Types         Exceptions         Tasks

Unit

Compress

Description

A TCompress component lets you manage a wide range of data compression  tasks. As well as managing multi-file archives and providing a range of file and stream compression capabilities,  it is essential for using the TCDBMemo and TCDBImage components.

While it has two forms of built-in compression and default handling for most situations, the events provided by this component mean you can provide your own user interface, and even your own specialist data compression routines (e.g. for fractal compression).

The RegName and RegNumber properties provide for registration of the component so that you will no longer see the occasional reminder dialog.

Two runtime properties, CompressedPercentage and CompressionTime, both provide information on the performance of the last compression or expansion operation.

See Using TCompress for more information on TCompress tasks. Also refer to the examples in the COMPDEMO application source.


Properties

TCompress:

Regname

RegNumber

CompressedPercentage (runtime)

CompressionTime (runtime)

TCDBMemo/TCDBImage

CompressionMethod

CompressSource

DataField

DataSource

CField

CompressedField (protected)

TCBlobfield:

CompressionMethod

CompressSource

TCBlobstream:

Blobstream


Methods

For multi-file archive files:

CompressFile

CompressFiles

ScanCompressedFile

ExpandFile

ExpandFiles

DeleteFiles

For multi-file archive streams:

CompressFilesToStream

ScanCompressedStream

ExpandFilesFromStream

For single-item stream to stream:

Compress

Expand

For stream to stream without header:

DoCompress

DoExpand

Recognize

Protected methods:

AppendFilesExcept (protected)

GetFileHeader (protected)

PutFileHeader (protected)

SetHeader (protected)

TruncateFile (protected)

TruncateStream (protected)


Exceptions

EUnrecognizedCompressionMethod

ComMethodID in the archive header is not recognized.

EInvalidHeaderArchiveType

The Archive type stored in the archive header is not valid for this operation. For example, an individual file which has been saved with the single-item Compress method is being expanded with the multi-file ExpandFile method instead of the Expand method.

EInvalidHeader

Unable to find a valid comID at the start of an archive header.

EBadChecksum

Data which has just been expanded does not have the same checksum as the original data before it was compressed. Data corruption or data access problems are the most likely causes.

EInsufficientDiskSpace

Not enough disk space when expanding or compressing a file. This is most likely to occur during updates to large archives.


Events

OnCheckFile

OnCompress

OnExpand

OnRecognize


Types

TCompress Types:

TCompressionMethod

TCProcessMode

TCompressedFileInfo

TCompressArchiveType

TCompressHeader

TCompressedFileHeader

TCDBImage/TCDBMemo Classes:

TCBlobField

TCBlobStream


RegName Property

Applies to

TCompress component.

Declaration

property RegName:String;

Description

Once you have registered your copy of TCompress, this property should be set to your registered name, e.g. Peter Hyde.

In conjunction with the RegNumber property, this will eliminate the occasional reminder dialog.


RegNumber Property

Applies to

TCompress component.

Declaration

property RegNumber: Longint;

Description

Once you have registered your copy of TCompress, this property should be set to your personal registration number, e.g. 12345.

In conjunction with the RegName property, this will eliminate the occasional reminder dialog.


CompressedPercentage Property

Applies to

TCompress component.

Declaration

property CompressedPercentage: Integer;

Description

This runtime property notes the percentage effectiveness of the last compression operation.

For example, 0% means it has failed to compress the data at all, and the original data has been saved instead; 95% means the compressed data is only 5% the size of the original data.


CompressionTime Property

Applies to

TCompress component.

Declaration

property CompressionTime: Longint;

Description

This runtime property notes how long the last compression or expansion operation took, expressed in 1ms clock ticks.

The timing is limited to the compression/expansion operation itself, not any associated overheads such as file or database opening.

The compression time for TCDBMemo/TCDBImage fields cannot be reliably judged. This is because the Borland Database Engine usually follows a record write by one or more reads. By the time you get a chance to check CompressionTime, it holds the time of the expansion that occurred during the last read operation.


TCompressionMethod Type

Unit

Compress

Declaration

TCompressionMethod = ( coNone,             no data compression -- just store

                                      coRLE,              compress with RLE

                                      coLZH,              compress with LZH

                                      coCustom );       compress with Custom method

Description

These constants are used in calling various TCompress methods, and also to set the CompressionMethod property of the TCDBMemo and TCDBImage components.

Only use coCustom if you have provided suitable handlers for the OnCompress, OnExpand and OnRecognize events.


TCProcessMode Type

Unit

Compress

Declaration

TCProcessMode = ( cmCompress,           compress operation

                              cmExpand,               expand operation

                              cmDelete);                file delete operation

Description

These constants are used in the OnCheckFile event to tell your handler what operation is in progress so you can amend your user interface or filename handling as required.


TCompressedFileInfo Type

Unit

Compress

Declaration

TCompressedFileInfo = Class(TObject)

 public

   Datetime: Longint;                            original file date and time

   Fullsize: Longint;                              original file size

   Attributes: Smallint;                          original file attributes

   CompressedSize: Longint;                 compressed file size

   CompressedMode:   TCompressionMethod;    how compressed

   Checksum: Longint;                         original file data checksum

   Position: Longint;                             start of File header in the archive

end;

Description

An instance of this object is created and assigned to each element of the TStringList which is filled by the ScanCompressedFile or ScanCompressedStream method.

You can use it to determine and/or display information such as the original file's creation date and attributes or the compression percentage.

Warning: While instances of this object are created automatically, it is up to you to free them when you have finished with the TStringList. For an example of this, see the code in the FormDestroy method of COMPDEMO.


TCompressArchiveType

Unit

Compress

Declaration

TCompressArchiveType =

                        ( caSingle,            single item archive (no file headers)

                          caMulti );            multi-file archive (file header for each)

Description

These constants are used in the archive header of each archive to note what kind of archive it is.


TCompressHeader Type

Unit

Compress

Declaration

TCompressHeader =

  Record

    ComId: array[0..4] of char;                        Always SPIS + chr(26)

    ComMethodId: array[0..2] of char;             RLE, LZH, NON, CUS/user-defined

    Fullsize: Longint;                                     excl. header, not used for caMulti

    ArchiveType: TCompressArchiveType;       caSingle, caMulti

    Checksum: Longint;                                checksum value, not used caMulti

    Reserved: Longint;                                  as it says

 end;

Description

Every compressed archive (whether single-item or multi-file) starts with a copy of this header.

If the header is missing, data is read and treated as if it was not compressed. For example, the Compress method will store the original data with no header if the compressed data size was not smaller than the original.

If it is a multi-file archive, this header is immediately followed by the first file header, followed in turn by the compressed copy of that file.


TCompressedFileHeader Type

Unit

Compress

Declaration

TCompressedFileHeader =

  Record

    FilenameLength: Smallint;          filename itself immediately follows this header

    Datetime: Longint;                     original file date and time

    Attributes: Smallint;                   original file attributes

    Fullsize: Longint;                       original file size

    CompressedSize: Longint;         size of compressed copy of the file

    CompressedMode: TCompressionMethod;       how compressed

    Checksum: Longint;                  checksum value of original file, 0 if coNone

    Reserved: Longint;

 end;

Description

In a multi-file archive, the archive header is followed by 0 or more repeats of this header, each followed by its filename and then its compressed file data.

The filename is max 255 characters long, and is always stored in lower case with no drive letter (although a path may be stored if desired).

Note that compressedMode can vary from file to file in a single archive.

Registered users can refer to source code examples which use this structure in ARC2MEM.PAS or ARC2BLOB.PAS.


TCBlobfield Component

TCMemofield        See also: TMemofield

TCGraphicfield    See also: TGraphicfield

Unit

Compctrls

Description

This component and its two derivatives are themselves derived from Delphi's TBlobfield component.

In effect, TCBlobfield instances supplant regular TBlobfields when you are performing database access with compression.

Normally, an appropriate TCBlobfield will be created for you automatically if you are using a TCDBMemo or TCDBImage component. However, you can create a TCBlobfield in code to access and compress any blob field. For example, you might do this for a field containing sound data. Registered users can refer to the source example in BLOBDEMO.PAS.

To support compression, TCBlobfield and its derivatives have two additional properties: CompressionMethod and CompressSource.

Database access (and compression/expansion) operations on TCBlobfields are performed by creating and using a TCBlobstream object.


TCGraphicfield Component

See TCBlobfield component.


TCMemofield Component

See TCBlobfield component.


TCBlobStream Object

Unit

Compctrls

Description

This component is equivalent Delphi's TBlobstream object, with a full range of matching properties and methods.

However, it has several subtle operational differences:

The Create method requires a TCBlobfield or derivative as its first parameter, rather than the TBlobfield required by TBlobstream's Create. The second parameter is the mode (bmRead or bmWrite, as required).

When created for reading a TCBlobfield, a TCBlobstream will immediately read into memory the entire contents of the field, automatically decompressing it if required. All subsequent read/write operations access the decompressed data in memory.

When created for writing a field, the TCBlobstream stores all data written to it in memory until it is freed, at which point the data is compressed (if required) and written to the database.

In bmRead mode, the Size property returns the actual (decompressed) size of the field data. In bmWrite mode, it will be the larger of the field's DataSize property, or however many bytes have already been written.

If you need to directly access the underlying (possibly compressed) data in the database, use the read-only Blobstream property which provides a regular TBlobstream handle to the field data. If you do this, you should not use the regular TCBlobstream methods and properties at the same time. Registered users can refer to the source example in ARC2BLOB.PAS.


OnCheckFile Event

Declaration

procedure CheckFile(var filepath: String;  mode: TCProcessMode);

Description

This event is called just before the multi-file action referred to by mode takes place for the current filepath.

This gives you the opportunity to seek user confirmation and:

•	Skip the operation for the file in question by setting filepath to CompressSkipFlag.

•	Skip this and all subsequent files by setting filepath to CompressNoMoreFlag

•	Amend filepath so that it is either compressed with or expanded to a different path

When mode is cmCompress, filepath is the full path of the original file as passed to CompressFiles -- you can leave it as-is if you want path information stored in your archive, or shorten it to filename.ext. Note that any drive designation is automatically removed after this call, and the filepath is converted to lower case.

When mode is cmExpand, filepath is the one that has been stored in the archive. If you don't amend it, the file will be expanded into that path (or into the current directory if there is no path). Alternatively, you can alter filepath to have it expanded into some other directory, or with some other filename.

See the Compress1CheckFile method in COMPDEMO for an example of a handler for this event.


OnCompress Event

Declaration

procedure OnCompress(dest, source: TStream;  var compressID: OpenString; var outputsize: Longint; var checksum: Longint);

Description

This event is called when custom compression has been requested by specifying a  compression method of coCustom.

Your handler must:

•	Set a three-letter compression ID in compressID (preset default is 'CUS')

•	Compress the data from the source stream into the dest stream, using only methods common to all stream types, including write, read and seek.

•	Leave both stream positions at the end of the read/written areas

•	Count the precise number of bytes output to dest and set the outputsize variable accordingly

•	Optionally calculate a checksum of the source data for validation on expansion (preset default is 0)

Notes

•	No header management is required by your routine -- a header has already been placed in the dest stream prior to this call, and will be updated after the call if required.

•	If your compression method increases the size of the data, the calling method will take care of storing a literal copy of the original rather than your compressed version (isn't that kind?).

•	See the comments in OnRecognize on version management using compressID.

•	Registered users should see the source code example of an OnCompress handler for LZW compression in LZWCOMP.PAS.


OnExpand Event

Declaration

procedure OnExpand(dest, source: TStream;  sourcesize, destsize: Longint; compressID: String; var checksum: Longint);

Description

This event is called when expansion has been requested by using   coCustom compression method.

Your handler must:

•	Decompress from source to dest, using only the methods common to all stream types including write, read and seek.

•	Respect the sourcesize setting, reading exactly that many bytes and no more. The destsize parameter is the original uncompressed file size, which some algorithms (e.g. LZH) require.

•	Leave the stream positions at the end of the read/written areas.

•	Calculate and set a checksum value (preset default 0) which the calling routine will verify against the checksum made when the data was compressed.

Notes

•	The compressID string is passed to you in case you need it to decode version information. See OnRecognize.

•	No header processing is required from your handler -- the source stream starts out positioned at the first byte of compressed data.

•	Registered users should see the source code example of an OnExpand handler for LZW compression in LZWCOMP.PAS.


OnRecognize Event

Declaration

procedure OnRecognize(compressID: String;  var recognized: Boolean);

Description

This event is called when a custom compressID has been found in the archive header.

Your handler must:

•	''Recognize'' compressID by setting recognized to true if it is valid (preset default is false).

Notes

•	ID values NON, RLE and LZH are reserved.

•	By requiring you to recognize the three-character compression ID, this event is allowing for the possibility that a TCompress archive has been compressed with one custom handler, and may now be attempting decompression with another.

•	You may choose to recognize multiple IDs, reflecting either differing compression methods or (more likely) different versions of your original method.

•	Depending on your application, it is very desireable to continue to support an old compression format, even if you later supercede it with a new version. Thus, you may end up recognizing ids such as FRA, FRB and FRC.


CompressFile Method

Declaration

procedure CompressFile(arcFile: String; var fromFile: String; compressionMode: TCompressionMethod);

Description

A simple single-file interface to the functions provided by CompressFiles.  The fromfile parameter may be amended or set to an empty string if an OnCheckFile event handler is defined.


CompressFiles Method

Declaration

procedure CompressFiles(arcFile: String; whichfiles: TStringList; compressionMode: TCompressionMethod);

Description

Compresses one or more files from the whichfiles list into the arcfile multi-file archive.

If arcfile already exists,  the files are updated or appended as appropriate.

If an OnCheckFile event handler is defined, it will be called with a process mode of cmCompress before each file is compressed.

When CompressFiles returns, whichfiles contains only those files which were actually compressed (with the paths set by OnCheckFile).

CompressFile provides a simpler single-file interface to this method.

See COMPDEMO for an example of the use of this method.


ScanCompressedFile Method

Declaration

procedure ScanCompressedFile(arcfile: String; var finfo: TStringList);

Description

This method scans the arcfile multi-file archive and returns a list of the archive's files in finfo.

Also sets each object element in finfo to an instance of the TCompressedFileInfo object.

See COMPDEMO for an example of the use of this method.


ExpandFile Method

Declaration

procedure ExpandFile(var toFile: String; arcFile: String);

Description

A simple single-file interface to the functions provided by ExpandFiles. The tofile parameter may be amended or set to an empty string if an OnCheckFile event handler is defined.


ExpandFiles Method

Declaration

procedure ExpandFiles(arcFile: String; whichfiles: TStringList);

Description

Expands one or more files in whichfiles from the arcfile multi-file archive.

If an OnCheckFile event handler is defined, it will be called with a process mode of cmExpand before each file is expanded.

When the ExpandFiles returns, whichfiles contains only those files which were actually expanded (with the actual paths set by OnCheckFile).

ExpandFile provides a simpler single-file interface to this method.

See COMPDEMO for an example of the use of this method.


DeleteFiles Method

Declaration

procedure DeleteFiles(arcFile: String; whichfiles: TStringList);

Description

Deletes one or more files in whichfiles from the arcfile multi-file archive.

If an OnCheckFile event handler is defined, it will be called with a process mode of cmDelete for each file before any file is deleted.

When the DeleteFiles returns, whichfiles contains only those files which were actually deleted.

See COMPDEMO for an example of the use of this method.


CompressFilesToStream Method

Declaration

function CompressFilesToStream(dest: TStream; whichfiles: TStringList; compressionMode: TCompressionMethod): Longint;

Description

This method is called by the CompressFiles method and is very similar.

The main differences are:

•	The files are compressed into the dest stream, which can be of any stream type, e.g. TFileStream, TMemoryStream or TBlobStream. This means that you can, for example, compress a number of files into a database blob using multi-file archive format.

•	Unlike CompressFiles, this method will not handle updating or appending of files in the archive. If there is already data in the dest stream, it is overwritten (from the current position) with a new multi-file archive containing the files in whichfiles.

•	The function return value is normally zero. However, if the contents of dest are smaller than the data it formerly held (if any), the stream may need to be truncated by the caller. This is normally only required for TFileStreams, as the other types can be truncated directly. The return value is the position at which the file must be truncated (see TruncateFile).

•	While there are stream-based methods for expanding files (ExpandFilesFromStream) and scanning the archive (ScanCompressedStream), there is no method similar to DeleteFiles.


ScanCompressedStream Method

Declaration

procedure ScanCompressedStream(compressedStream: TStream; var finfo: TStringList);

Description

This method is an exact analogy of the ScanCompressedFile method except that the scan is performed from the dest stream.

See CompressFilesToStream for more information about how streams may be used for flexible multi-file archive storage.


ExpandFilesFromStream Method

Declaration

procedure ExpandFilesFromStream(compressedStream: TStream; whichfiles:  TStringList);

Description

This method is an exact analogy of the ExpandFiles method except that the expand is performed from the dest stream.

See CompressFilesToStream for more information about how streams may be used for flexible multi-file archive storage.


Compress Method

Declaration

procedure Compress(compressedStream, uncompressedStream: TStream; compressionMethod: TCompressionMethod);

Description

This compression routine is for single-item archives rather than the multi-file archives supported by CompressFiles et al.

For example, this method is used for compression of database memos and images by TCDBMemo and TCDBImage.

You can use it with any stream type, such as TFileStream, TMemoryStream or TBlobStream.

The compressed data is stored in compressedStream with a small header indicating the compression method. If the compressed data is larger than the uncompressed original, the header is eliminated and the original is stored instead.

Expand is used to expand data which has been compressed using this method.


Expand Method

Declaration

procedure Expand(expandedStream,unexpandedStream: TStream);

Description

This expands single-item archives created with Compress, rather than the multi-file archives supported by CompressFiles et al.

For example, this method is used for expansion of database memos and images by TCDBMemo and TCDBImage.

You can use it with any stream type, such as TFileStream, TMemoryStream or TBlobStream.

The compressed data is read from unexpandedstream and written to expandedStream. If the data in unexpandedstream has no archive header, it is assumed to have been stored in its original (uncompressed) form.


DoCompress Method

Declaration

function DoCompress(compressedStream, uncompressedStream: TStream; compressionMethod: TCompressionMethod; var compressID: String;  var checksum: Longint): Longint;

Description

This is the lowest level public function offered by TCompress. It compresses the data from the current position in uncompressedStream, writing it to the current position in compressedStream.

CompressionMethod determines the compression format to be used, and a checksum of the uncompressed data is returned (0 for coNone). The function return value is the compressed data size in bytes.

Iif compressionMethod is coCustom, compressID may be altered by the OnCompress event handler.

Generally speaking, you will not need to use this function directly.


DoExpand Method

Declaration

procedure DoExpand(expandedStream, unexpandedStream: TStream; compressedSize, fullSize, checksum: Longint; compressionMethod: TCompressionMethod; compressID : String);

Description

This low-level method is used to expand bytes directly from one stream to another. It expands exactly compressedSize bytes from the current position in unexpandedStream, writing the result to the current position in expandedStream. The fullSize parameter is the original uncompressed file size, which some algorithms (e.g. LZH) require.

CompressionMethod specifies the compression format which is expected, and the checksum is compared against a newly-calculated checksum of the expanded data (except in the case of compression method coNone).

CompressID should be specified when compressionMethod is coCustom, but may be an empty string for the other modes.

One useful application of this method is to expand a file directly from the current location in a multi-file archive to a memory or blob stream. An example which does this is provided to registered users.


Recognize Method

Declaration

function Recognize(cID: String): TCompressionMethod

Description

This function simply returns the correct compression method based on the 3-character string in cID. An exception will occur if it is not recognized either as a built-in compression method, or a supported custom format (as recognized by an OnRecognize event handler).

Use this method if you are directly manipulating an archive and need to obtain the right mode to call DoExpand after reading the ComMethodID from the archive header.

Note

You must convert ComMethodID from a array of char into a string before calling this method.


AppendFilesExcept Method

Declaration      (protected method)

procedure AppendFilesExcept(destfile, fromfile: String; notfiles: TStringList);

Description

This method assumes that both destfile and fromfile are multi-file archives. It appends all the compressed files in fromfile to destfile, except those in the notfiles list.

If destfile does not exist, it is created and will end up containing either a full copy or a subset of fromfile, depending on the contents of notfiles.

This method is called by CompressFiles and DeleteFiles.


GetFileHeader Method

Declaration      (protected method)

function GetFileHeader(Stream: Tstream; var Fhdr: TCompressedFileHeader; var Filename: String): Boolean;

Description

This method tries to read Fhdr and Filename from the current position in Stream. Returns True if the reads are successful (data is not validated).


PutFileHeader Method

Declaration      (protected method)

procedure PutFileHeader(Stream: Tstream; var Fhdr: TCompressedFileHeader; Filename: String);

Description

This method sets Fhdr.FileNameLength and then writes FHdr and Filename to the current position in Stream.


SetHeader Method

Declaration      (protected method)

procedure SetHeader(var hdr: TCompressHeader; cID: String; aType: TCompressArchiveType; size: Longint);

Description

This method initializes the archive header in hdr, based on the data in cID (a 3-character compression ID), aType and size.

It is called by CompressFilesToStream and Compress.


TruncateFile Method

Declaration      (protected method)

procedure Truncatefile(filename: String; truncatepos: Longint);

Description

This method truncates the file indicated by filename at the position truncatepos.

It is called by CompressFiles if CompressFilesToStream returns a non-zero value after updating an archive.


TruncateStream Method

Declaration      (protected method)

function TruncateStream(dest:  TStream; truncatepos: Longint): Longint;

Description

This method checks the dest stream type. If it is a TMemoryStream or TBlobStream, it is truncated at truncatepos and the return value is zero.

If it is a THandleStream (which includes TFileStream), the truncation cannot be performed while the file is open, so the return value is truncatepos. This indicates that TruncateFile should be called after the file has been closed.

This method is called by Compress and CompressFilesToStream.


    TCDBMemo Component

Properties         Tasks         See also:  TDBMemo,  TMemo

Unit

Compctrl

Description

A TCDBMemo component provides the same capabilities as Delphi's TDBMemo, except that it can automatically read and write compressed text from the database.

The data compression features will not be enabled unless you link the TCDBMemo to a TCompress component by setting the CompressSource property.

You should also set the CompressionMethod property, as the default compression is none (coNone).

The DataField and DataSource properties are the same as those for a TDBMemo, apart from one  important design-time difference which is detailed in the DataSource property information.

The CField run-time property provides access to the underlying TCMemoField which provides the database access and compression.

See Using TCDBMemo and the COMPDEMO application for more information and examples of use.


CompressionMethod Property

Applies to

TCDBMemo, TCDBImage components, TCBlobfield object.

Declaration

property CompressionMethod: TCompressionMethod;

Description

This determines what compression method will be used when this field is saved.

The method used will be auto-detected on expansion. Thus, there is no danger in varying the compression method between compressions if you so wish.

It is always possible that the data cannot be compressed, in which case it will be saved in its original form, with no archive header.


CompressSource Property

Applies to

TCDBMemo, TCDBImage components, TCBlobfield object.

Declaration

property CompressSource: TCompress;

Description

This links the database component to a TCompress object which will handle data compression and expansion for it.


DataField Property

Applies to

TCDBMemo, TCDBImage components.

Declaration

property DataField: TField;

Description

This is just the same as the regular DataField property.

However, you should be aware of an important design-time difference which is detailed in the DataSource property.


DataSource Property

Applies to

TCDBMemo, TCDBImage components.

Declaration

property DataSource: TDataSource;

Description

This is exactly as it would be for a regular TDBMemo or TDBImage, with one important difference:

Special Note:

The dataset (TTable or TQuery) to which the DataSource is linked must not initially contain the same DataField as the one specified in the TCDBMemo or TCDBImage.

Thus, if your TCDBImage component has a DataField of Graphic, and its DataSource is linked to Table1, then Table1 should not (initially) have a Graphic field in its field list.

If it does, you will see the following warning:

TCompress warning: Table1 already has a non-compressed

field called 'Graphic'.

Double click on Table1, remove the existing field, and try again.

The reason for the message is that Table1's regular TBlobfield cannot handle compression and must be supplanted by a TCBlobfield which can. Unfortunately, Delphi's implementation does not make it possible for TCDBImage or TCDBMemo to make this kind of replacement automatically.

Once you have removed the old field, specify your TCDBImage's DataField property again to create its TCBlobfield replacement. The Graphic field may subsequently reappear in Table1's field list -- that's ok, as it will be the one created by TCDBImage.


CField Property

Applies to

TCDBMemo, TCDBImage components.

Declaration

property CField: TCBlobfield;

Description

Runtime and read-only. This is just a public read-only version of the protected CompressedField property.


CompressedField Property

Applies to

TCDBMemo, TCDBImage components.

Declaration

property CompressedField: TCBlobfield;

Description

Runtime only. The TCBlobfield provides a handle for all access to the field data, handling compression and expansion as required.


Blobstream Property

Applies to

TCBlobstream object.

Declaration

property Blobstream: TBlobstream;

Description

Runtime and read only. This is a regular TBlobstream which can be used to directly access the underlying (and probably compressed) data in a TCBlobfield.

If you use this property for any data access, you should not also use the data access methods and properties native to the TCBlobstream, because these maintain and manipulate independent in-memory buffers until you free the TCBlobstream.

See the TCBlobstream object for more information.


    TCDBImage Component

Properties         Tasks         See also:  TDBImage,  TImage

Unit

Compctrl

Description

A TCDBImage component provides the same capabilities as Delphi's TDBImage, except that it can automatically read and write compressed images from the database.

The data compression features will not be enabled unless you link the TCDBImage to a TCompress component by setting the CompressSource property.

You should also set the CompressionMethod property, as the default compression is none (coNone).

The DataField and DataSource properties are the same as those for a TDBImage, apart from one  important design-time difference which is detailed in the DataSource property information.

The CField run-time property provides access to the underlying TCGraphicField which provides the database access and compression.

See Using TCDBImage and the COMPDEMO application for more information and examples of use.


Troubleshooting

If you get a runtime exception, see exceptions.

If you see a Duplicate field name error when using TCDBMemo or TCDBImage, see the special note in the DataSource property information.

Any minor updates to TCompress will be issued to BBS, Web and ftp sites worldwide -- you should check the date and time of their COMPRESS.ZIP against your own (all file times in this version are 1:50). You can also check:

Web page: http://super.sonic.net/ann/delphi/more

Ftp site: ftp.sonic.net   in   /pub/mall/moreDelphi/compress.zip

If you suspect there is a problem with TCompress, TCDBMemo or TCDBImage, please contact us with the following information:

•	Your version of Delphi (and any patches applied)

•	Your version of Windows

•	Your version of these components (see the help window title above)

•	What you were doing, and what went wrong (be as precise as possible, and do check whether the error can be replicated after a reboot).

•	If possible, a copy of the data being compressed/expanded, and enough source code from your application to allow us to independently repeat the problem.

Send the above information to South Pacific Information Services Ltd via any of the methods listed at the very end of the registration section.